package cn.cmcc.online.smsapi.sdk.net.util;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.log.LogManager;

/**
 * 签名或验证
 * @author lenovo
 *
 */
public class Signaturer {
	
//	public static final String	PRIVKEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJcC4TVIXTjxeprJlfYkfil8K4jor7DZcdC6fwFvsORXTV+Y79paLPJuMx3IWR9JYP/R4HPIyCLWH2LZxivjEpzmN6oR0VSJIkCIspTKtuL6atKJxoilQG5glTguXqcdNlez9KTPhTMsilWWEt9j7WaQ+q6Xi5+2fuMbDkm2y/UnAgMBAAECgYBdTV4wOaG/iROjh2GsTyfUIfAUCxBiSDdWK6RFEulMa9RWeHvZgVW8A/J5OEw4VHImHVp8r1VYkMubm8ohW48ng6NjjXgSOxBhe7wfZOkBEDGr/NfhnUt7yr3y/r45qjLeivMixyYerc+iODlQfTXuL0LlJGgey9MpJPSgfvLlgQJBAOfJKNqFXeSkUuu4Q3Q1e0gtNRORkshBDrYF8kOwthEyEbacQF9sEpwqnkyOyfAOs6OdujrzawatqW6pYUnNFNcCQQCmyX/eya079MhjG0ZUqCkZOas6cy5TeCWWuNzJQ9oU9zG/OZrR6P2j7tNvRnm1EybriRTJWrVIC1vDHiPodcgxAkAcnn3o3WbGgHOsn0fU5XWfZ9WR4Puatk22s+1B5mPUo7YEMi7QmWuC1NBO66KLfYU4wpToCn5AiNjOzSMyFZxpAkEAmn1w3UuQFEZDy1E7TzVIhF4flg+UrKpQnxDzKdaYzey+/rL8Dk2zi8KvxJXSLIDl/yxFvdEws+AZil2Dw1I+MQJAfcmSGmddExxUwPYcBqyQaD2yTeP5q+DEsJLJJejyIdJqJu/UxKVrmwaCWLNgT1EZkpV+TvR9HIEjyDH/DYDHsg==";

	/**
	 * 用私钥签名
	 * @param priKeyText 私钥
	 * @param plainText 签名的原文
	 * @return 签名结果
	 */
	 public static String  sign(String priKeyText, String plainText) {
		return new String(sign(priKeyText.getBytes(), plainText)).replaceAll("\r\n", "").replaceAll("\n", "");
	 }
	 
//	 public static String  sign(String priKeyText, String plainText,String algorithm) {
//			return new String(sign(priKeyText.getBytes(), plainText,algorithm)).replaceAll("\r\n", "").replaceAll("\n", "");
//	 }
	 /**
	  * 验证签名
	  * @param pubKeyText 公钥
	  * @param plainText 签名的原文
	  * @param sign 签名后的内容
	  * @return true 验证成功，false 失败。
	  */
	 public static boolean  verify(String pubKeyText, String plainText,String sign) {
			return verify(pubKeyText.getBytes(), plainText,sign.getBytes());
	 }
	 /**
	  * 
	  * Description:数字签名
	  * @param priKeyText
	  * @param plainText
	  * @return
	  */
	 public static byte[] sign(byte[] priKeyText, String plainText) {
	  try {
	   PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64
	     .decode(priKeyText));
	   KeyFactory keyf = KeyFactory.getInstance("RSA");
	   PrivateKey prikey = keyf.generatePrivate(priPKCS8);

	   // 用私钥对信息生成数字签名
	   java.security.Signature signet = java.security.Signature			  
	     .getInstance("SHA256WithRSA");
	   

	   signet.initSign(prikey);
	   signet.update(plainText.getBytes());
	   byte[] signed = Base64.encodeToByte(signet.sign());
	   return signed;
	  } catch (java.lang.Throwable e) {
//	      LogManager.e("Signaturer","sign failed",e);
//	   e.printStackTrace();
          LogManager.e(Constant.TAG, "sign error ", e);

	  }
	  return null;
	 }
	 
	 public static byte[] sign(byte[] priKeyText, String plainText,String algorithm) {
		  try {
		   PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64
		     .decode(priKeyText));
		   KeyFactory keyf = KeyFactory.getInstance("RSA");
		   PrivateKey prikey = keyf.generatePrivate(priPKCS8);

		   // 用私钥对信息生成数字签名
		   java.security.Signature signet = java.security.Signature
		     .getInstance(algorithm);
		   signet.initSign(prikey);
		   signet.update(plainText.getBytes());
		   byte[] signed = Base64.encodeToByte(signet.sign());
		   return signed;
		  } catch (java.lang.Throwable e) {
//		      LogManager.e("Signaturer","sign failed",e);
//		   e.printStackTrace();
	            LogManager.e(Constant.TAG, "sign: error", e);

		  }
		  return null;
		 }
	
	 /**
	  * 
	  * Description:校验数字签名,此方法不会抛出任务异??成功返回true,失败返回false,要求全部参数不能为空
	  * 
	  * @param pubKeyText
	  *            公钥,base64编码
	  * @param plainText
	  *            明文
	  * @param signTest
	  *            数字签名的密文base64编码
	  * @return 校验成功返回true 失败返回false
	  */
	 public static boolean verify(byte[] pubKeyText, String plainText,
	   byte[] signText) {
		try {
			// 解密由base64编码的公??并构造X509EncodedKeySpec对象
			java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
					Base64.decode(pubKeyText));
			// RSA对称加密算法
			java.security.KeyFactory keyFactory = java.security.KeyFactory
					.getInstance("RSA");
			// 取公钥匙对象
			java.security.PublicKey pubKey = keyFactory
					.generatePublic(bobPubKeySpec);
			// 解密由base64编码的数字签??
			byte[] signed = Base64.decode(signText);
			java.security.Signature signatureChecker = java.security.Signature
					.getInstance("SHA256WithRSA");
			signatureChecker.initVerify(pubKey);
			signatureChecker.update(plainText.getBytes());
			// 验证签名是否正常
			if (signatureChecker.verify(signed))
				return true;
			else
				return false;
		} catch (Throwable e) {
//		    LogManager.e("Signaturer","sign failed",e);
//			e.printStackTrace();
            LogManager.e(Constant.TAG, "verify: error ", e);

			return false;
		}
	 }
	 
		/***
		 * SHA256加密 生成64位SHA码
		 * @param 待加密字符串
		 * @return 返回64位SHA码
		 */
		public static String sha256Encode(String inStr){
			MessageDigest sha = null;
			try {
				sha = MessageDigest.getInstance("SHA-256");
				byte[] byteArray = inStr.getBytes("UTF-8");
				byte[] md5Bytes = sha.digest(byteArray);
				StringBuffer hexValue = new StringBuffer();
				for (int i = 0; i < md5Bytes.length; i++) {
					int val = ((int) md5Bytes[i]) & 0xff;
					if (val < 16) {
						hexValue.append("0");
					}
					hexValue.append(Integer.toHexString(val));
				}
				return hexValue.toString();
			} catch (Throwable e) {
	            LogManager.e(Constant.TAG, "sha256Encode error ", e);

				return "";
			}
		}
}

